package com.hyjx.framework.component.log;

import com.hyjx.framework.common.CommonUtil;
import com.hyjx.framework.common.util.SpringBeanUtil;
import com.hyjx.framework.common.util.StringHelper;
import com.hyjx.framework.component.operatelog.OperatelogModel;
import com.hyjx.framework.component.operatelog.OperatelogStatus;
import com.hyjx.framework.component.operatelog.operatelogdetail.OperatelogDetailModel;
import com.hyjx.framework.orm.dao.IBaseDao;
import com.hyjx.framework.service.ConfigManager;
import com.hyjx.framework.service.SessionManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 基础日志切面类
 */
@Aspect
@Component
public class LogBaseDaoAspect {
    Logger log = LoggerFactory.getLogger(LogBaseDaoAspect.class);
    @Resource
    private IBaseDao dao;
    
    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    private void anymethod() {
    }
    
    @Before("anymethod()")
    public void before() {
        OperatelogStatus.start = System.currentTimeMillis();
    }
    
    @After("anymethod()")
    public void after() {
        OperatelogStatus.end = System.currentTimeMillis();
    }
    
    /**
     * 日志入库
     *
     * @param joinPoint
     * @return
     *
     * @throws Throwable
     */
    @Around("anymethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        if (!"1".equals(ConfigManager.getConfig("logIntereptor.datalog"))) {
            return joinPoint.proceed();
        }
        String lbid = "";
        if (RequestContextHolder.getRequestAttributes() != null) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

            lbid = SessionManager.getString("lbid");
        }
        if (lbid == null || lbid.trim().length() == 0) {
            return joinPoint.proceed();
        }
        
        Object obj = null;
        Object[] os = joinPoint.getArgs();
        LogBusinessDataModel lbd = new LogBusinessDataModel();
        lbd.setLbid(lbid);
        if (joinPoint.getStaticPart().toString().indexOf(".updateObject") > -1) {
            LogBusinessDataModel lbdm = this.addoplog(String.valueOf(os[0]), os[1], true, lbd);
            obj = joinPoint.proceed();
            this.addoplog(String.valueOf(os[0]), os[1], false, lbdm);
        } else if (joinPoint.getStaticPart().toString().indexOf(".addObject") > -1
                || joinPoint.getStaticPart().toString().indexOf("nsertObject") > -1) {
            obj = joinPoint.proceed();
            this.addoplog(String.valueOf(os[0]), os[1], false, lbd);
        } else if (joinPoint.getStaticPart().toString().indexOf(".deleteObject") > -1) {
            this.addoplog(String.valueOf(os[0]), os[1], true, lbd);
            obj = joinPoint.proceed();
        } else {
            obj = joinPoint.proceed();
        }
        return obj;
    }
    
    /**
     * 添加日志
     *
     * @param sqlname
     * @param param
     * @param beforeupdate
     * @param lbd
     * @return
     */
    @SuppressWarnings("unchecked")
    private LogBusinessDataModel addoplog(String sqlname, Object param, boolean beforeupdate, LogBusinessDataModel lbd) {
        if (sqlname.indexOf("logbusinessdata") > -1) {
            return null;
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        LogBusinessDataModel retm = new LogBusinessDataModel();
        retm.setLbid(lbd.getLbid());
        try {
            LogBusinessDataModel m = new LogBusinessDataModel();
            m.setLbid(lbd.getLbid());
            m.setLdid(StringHelper.getPrimaryKey());
            String sql = dao.getCurrSql(param, sqlname).trim();
            //m.setSql(sql);
            if (sql.toLowerCase().startsWith("insert")) {
                try {
                    String tname = sql.substring(sql.toLowerCase().indexOf("into") + 4, sql.indexOf("(")).trim();
                    m.setTablename("插入表 " + tname);
                    if (tname.indexOf(" ") > -1) tname = tname.split(" ")[0];
                    String where = " where " + sql.substring(sql.indexOf("(") + 1, sql.indexOf(",")) + "=" + sql.toLowerCase().split("values")[1].substring(sql.toLowerCase().split("values")[1].indexOf("(") + 1, sql.toLowerCase().split("values")[1].indexOf(","));
                    String sqlnewrec = "select * from " + tname + " " + where;
                    List<Map<String, String>> list = dao.queryObjectList(new OperatelogModel().getModuleName() + ".querymap", sqlnewrec);
                    String oldrec = CommonUtil.getJsonString(list);
                    //odmodel.setLastrec(oldrec);
                    m.setLastrec(oldrec);
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                    log.error("", e);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("", e);
                }
            } else if (sql.toLowerCase().startsWith("delete")) {
                try {
                    String tname = sql.substring(sql.toLowerCase().indexOf("from") + 5, sql.toLowerCase().indexOf(" where"));
                    m.setTablename("删除 " + tname + " 表数据");
                    String where = sql.substring(sql.toLowerCase().indexOf("where"), sql.length());
                    String sqloldrec = "select * from " + tname + " " + where;
                    List<Map<String, String>> list = dao.queryObjectList(new OperatelogModel().getModuleName() + ".querymap", sqloldrec);
                    String oldrec = CommonUtil.getJsonString(list);
                    //odmodel.setOrigrec(oldrec);
                    m.setOrigrec(oldrec);
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                    log.error("", e);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("", e);
                }
            } else if (sql.toLowerCase().startsWith("update")) {
//					if(sql.toLowerCase().indexOf(" where ")==-1)
//						return null;
                if (beforeupdate) {
                    try {
                        String tname = sql.substring(6, sql.toLowerCase().indexOf("set")).trim();
                        m.setTablename("更新表 " + tname);
                        String where = "";
                        if (sql.toLowerCase().indexOf(" where ") != -1) {
                            where = sql.substring(sql.toLowerCase().indexOf("where"), sql.length());
                        }
                        
                        String sqloldrec = "select * from " + tname + " " + where;
                        List<Map<String, String>> list = dao.queryObjectList(new OperatelogModel().getModuleName() + ".querymap", sqloldrec);
                        String oldrec = CommonUtil.getJsonString(list);
                        m.setOrigrec(oldrec);
                        SessionManager.set("sqloldrec", sqloldrec);
                        SessionManager.set("tempolid", m.getLdid());
                        retm.setLdid(m.getLdid());
                        retm.setSql(sqloldrec);
                    } catch (IndexOutOfBoundsException e) {
                        e.printStackTrace();
                        log.error("", e);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("", e);
                    }
                } else {
                    try {
                        List<Map<String, String>> list = dao.queryObjectList(new OperatelogModel().getModuleName() + ".querymap", SessionManager.get("sqloldrec"));
                        String newrec = CommonUtil.getJsonString(list);
                        m.setLastrec(newrec);
                        m.setLdid(SessionManager.get("tempolid") + "");
                        LogBusinessImpl logService = (LogBusinessImpl) SpringBeanUtil.getBean("logBusinessImpl");
                        logService.logbusinessdataupdate(m);
                        
                    } catch (IndexOutOfBoundsException e) {
                        e.printStackTrace();
                        log.error("", e);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("", e);
                    }
                    return null;
                }
            }
            m.setTimestamp(StringHelper.getDateTime());
            m.setSql(sql);
            LogBusinessImpl logService = (LogBusinessImpl) SpringBeanUtil.getBean("logBusinessImpl");
            logService.logbusinessdata(m);
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return retm;
    }
}
